<template>
  <div class="todo-container">
    <div class="todo-wrap">
      <Header :addtodo="addtodo"></Header>
      <List :todos="todos" :updatetodo="updatetodo"></List>
      <Footer
        :updatetodoall="updatetodoall"
        :todos="todos"
        :clearalldoned="clearalldoned"
      ></Footer>
    </div>
  </div>
</template>

<script lang="ts">
import {
  defineComponent,
  reactive,
  toRefs,
  onMounted,
  onBeforeUnmount,
  watch,
} from "vue";
import { nanoid } from "nanoid";
import pubsub from "pubsub-js";
import Header from "./components/Header.vue";
import List from "./components/List.vue";
import Footer from "./components/Footer.vue";
import { savetodos, gettodos } from "./util/todo";
import { Itodo } from "./util/type";

export default defineComponent({
  name: "App",
  components: {
    Header,
    List,
    Footer,
  },
  setup() {
    const data = reactive<{ todos: Itodo[] }>({
      todos: gettodos(),
    });
    // 添加todo
    function addtodo(val: string) {
      const newtodo: Itodo = {};
      newtodo.id = nanoid();
      newtodo.val = val;
      newtodo.done = false;
      data.todos.unshift(newtodo);
    }
    // 删除todo
    function deletetodo(_: string, id: string) {
      let index = data.todos.findIndex((item) => item.id == id);
      if (confirm("确认删除")) data.todos.splice(index, 1);
      return;
    }
    onMounted(() => {
      pubsub.subscribe("deleteitem", deletetodo);
    });
    // 完成todo状态
    function updatetodo(flag: boolean, id: string) {
      let index = data.todos.findIndex((item) => item.id == id);
      data.todos[index].done = flag;
    }
    // 完成全选和全不选
    function updatetodoall(flag: boolean) {
      data.todos.forEach((item) => (item.done = flag));
    }
    // 清除已经完成的
    function clearalldoned() {
      data.todos = data.todos.filter((item) => !item.done);
    }
    // 取消事件的派发
    onBeforeUnmount(() => {
      pubsub.unsubscribe(deletetodo);
    });
    // 监视todos 数据变化把数据存入localstroage
    watch(
      () => data.todos,
      (oldval, newval) => {
        savetodos(newval);
      },
      {
        deep: true,
      }
    );
    return {
      ...toRefs(data),
      addtodo,
      updatetodo,
      updatetodoall,
      clearalldoned,
    };
  },
});
</script>

<style lang="scss">
@import url("./assets/css/base.css");
.todo-container {
  width: 600px;
  margin: 0 auto;
  .todo-wrap {
    padding: 10px;
    border: 1px solid #ddd;
    border-radius: 5px;
  }
}
</style>
